home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Entertainment / tblt / tblt⁄record.c < prev    next >
Text File  |  1986-09-06  |  5KB  |  192 lines

  1. /*
  2.  * record.c - move recording/playback for the game of Tablut
  3.  */
  4.  
  5. #include <quickdraw.h>
  6. #include <window.h>
  7. #include <memory.h>
  8. #include "progerr.h"
  9. #include "tablut.h"
  10.  
  11. #define BT_NOBODY    0
  12. #define BT_SWEDE    1
  13. #define BT_MUSC        2
  14. #define BT_KING        3
  15.  
  16. #define BT_NOWIN    0
  17. #define BT_WHITEWIN    1
  18. #define BT_BLACKWIN    2
  19.  
  20. #define STATEBITS    2    /* bits required to store any BT_ value */
  21. #define STATEMASK    3    /* mask to extract adjusted STATEBITS    */
  22. #define BITSPERBYTE    8    /* number of bits per byte        */
  23.  
  24. struct moveblock *bdblockp;    /* pointer to the current memory chunk    */
  25. char *bdmovep;        /* pointer to the current state in that chunk */
  26.  
  27. /*
  28.  * initmoves() - setup the move-recording structures (called only once).
  29.  */
  30. initmoves()
  31. {
  32.     curmove = 0;
  33.     nummoves = 0;
  34.     bdblockp = &firstblock;
  35.     bdblockp->nxtblk = (struct moveblock *) 0;
  36.     bdmovep = &(bdblockp->bytes[0]);
  37. }
  38.  
  39. /*
  40.  * seekboard() - seek to the given move number in the game.
  41.  */
  42. seekboard(n)
  43. int n;        /* the move number to go to    */
  44. {
  45.     int blk;    /* the chunk index of the move    */
  46.     int idx;    /* the move index within that chunk    */
  47.     if (n >= nummoves) n = nummoves - 1;
  48.     if (n < 0) n = 0;
  49.     blk = n / BDPERBLK;
  50.     idx = n % BDPERBLK;
  51.     for (bdblockp = &firstblock; blk > 0; --blk) {
  52.     bdblockp = bdblockp->nxtblk;
  53.     }
  54.     bdmovep = &(bdblockp->bytes[BOARDBYTES * idx]);
  55.     curmove = n;
  56. }
  57.  
  58. /*
  59.  * readboard() - read the board state from the current position in
  60.  *  the record.
  61.  */
  62. readboard()
  63. {
  64.     int pidx;        /* temp piece-index            */
  65.     int kidx, sidx, midx; /* king, swede, and muscovite indices    */
  66.     int h,v;        /* coords                */
  67.     char *curbyte;    /* current byte within the move record    */
  68.     int bits;        /* bits representing a grid's state    */
  69.     int bitshift;    /* shift required to extract "bits"    */
  70.  
  71.     for (pidx = 0; pidx < NUMPIECES; ++pidx) {
  72.     hidepiece(pidx);    /* hide 'em so they move instantaneously  */
  73.     }
  74.     kidx = THEKING;
  75.     sidx = FIRSTSWEDE;
  76.     midx = FIRSTMUSC;
  77.     curbyte = bdmovep;
  78.     bitshift = 0;
  79.     for (h = -4; h <= 4; ++h) {
  80.     for (v = -4; v <= 4; ++v) {
  81.         bits = ((int)(*curbyte) >> bitshift) & STATEMASK;
  82.         switch (bits) {
  83.         case BT_KING:
  84.         if (kidx <= THEKING) placepiece(kidx++, h, v);
  85.         break;
  86.         case BT_SWEDE:
  87.         if (sidx <= LASTSWEDE) placepiece(sidx++, h, v);
  88.         break;
  89.         case BT_MUSC:
  90.         if (midx <= LASTMUSC) placepiece(midx++, h, v);
  91.         break;
  92.         }
  93.         if ((bitshift += STATEBITS) >= BITSPERBYTE) {
  94.         bitshift = 0;
  95.         ++curbyte;
  96.         }
  97.     }
  98.     }
  99.     while (midx <= LASTMUSC) removepiece(midx++);
  100.     while (sidx <= LASTSWEDE) removepiece(sidx++);
  101.     while (kidx <= THEKING)  removepiece(kidx++);
  102.  
  103.     bits = ((int)(*curbyte) >> bitshift) & STATEMASK;
  104.     switch(bits) {
  105.     case BT_WHITEWIN: winner = WHITEWIN; setsetup(1); break;
  106.     case BT_BLACKWIN: winner = BLACKWIN; setsetup(1); break;
  107.     default:          winner = NOWIN; break;
  108.     }
  109.     advmove(0);        /* advance the record without setting EOF */
  110. }
  111.  
  112. /*
  113.  * writeboard() - save the current state of the game.
  114.  */
  115. writeboard()
  116. {
  117.     int h,v;        /* coords                */
  118.     char *curbyte;    /* current byte within a move record    */
  119.     int bits;        /* bits representing a grid's state    */
  120.     int bitshift;    /* shift required to set "bits"        */
  121.     char *malloc();
  122.  
  123.     if (bdmovep >= &(bdblockp->bytes[BOARDBYTES * BDPERBLK])) {
  124.     /* allocate a new chunk of memory for recording    */
  125.     if (!(bdblockp->nxtblk =
  126.       (struct moveblock *) malloc(sizeof(struct moveblock)))) {
  127.         progstop(PE_NOMEM);
  128.         bomb();
  129.     }
  130.     bdblockp = bdblockp->nxtblk;
  131.     bdblockp->nxtblk = (struct moveblock *) 0;
  132.     bdmovep = &(bdblockp->bytes[0]);
  133.     }
  134.  
  135.     curbyte = bdmovep;
  136.     bitshift = 0;
  137.     for (h = -4; h <= 4; ++h) {
  138.     for (v = -4; v <= 4; ++v) {
  139.         bits = BT_NOBODY;
  140.         if ((*gridp)[h][v]) {
  141.         switch(classbase((*gridp)[h][v])) {
  142.         case FIRSTSWEDE: bits = BT_SWEDE; break;
  143.         case FIRSTMUSC:  bits = BT_MUSC;  break;
  144.         case THEKING:    bits = BT_KING;  break;
  145.         }
  146.         }
  147.         if (bitshift == 0) {
  148.         *curbyte = (char) 0;
  149.         }
  150.         *curbyte |= (char)(bits << bitshift);
  151.         if ((bitshift += STATEBITS) >= BITSPERBYTE) {
  152.         bitshift = 0;
  153.         ++curbyte;
  154.         }
  155.     }
  156.     }
  157.  
  158.     bits = BT_NOWIN;
  159.     switch(winner) {
  160.     case WHITEWIN: bits = BT_WHITEWIN; setsetup(1); break;
  161.     case BLACKWIN: bits = BT_BLACKWIN; setsetup(1); break;
  162.     }
  163.     if (bitshift == 0) {
  164.     *curbyte = (char) 0;
  165.     }
  166.     *curbyte |= (char)(bits << bitshift);
  167.     ischanged = 1;
  168.  
  169.     advmove(1);    /* advance, setting EOF    */
  170. }
  171.  
  172. /*
  173.  * advmove() - advance the record one move, optionally setting EOF
  174.  */
  175. advmove(seteof)
  176. int seteof;    /* if TRUE, the new state is the end one    */
  177. {
  178.     bdmovep += BOARDBYTES;
  179.     if (bdmovep >= &(bdblockp->bytes[BOARDBYTES * BDPERBLK])) {
  180.     if (bdblockp->nxtblk) {
  181.         bdblockp = bdblockp->nxtblk;
  182.         bdmovep = &(bdblockp->bytes[0]);
  183.     }
  184.     }
  185.     ++curmove;
  186.     if (seteof) {
  187.     nummoves = curmove;
  188.     }
  189.     fixlooker();
  190.     drawstate();
  191. }
  192.